package io.github.jsp.service.monitoring;

import io.github.jsp.executor.monitoring.ServiceMonitoringJobHandler.ServiceConfig;
import io.github.jsp.util.monitoring.HttpUtil;
import io.github.jsp.util.monitoring.NetworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class ServiceMonitoringService {
    
    private static final Logger logger = LoggerFactory.getLogger(ServiceMonitoringService.class);
    
    @Autowired
    private NetworkUtil networkUtil;
    
    @Autowired
    private HttpUtil httpUtil;
    
    @Autowired
    private AlertService alertService;
    
    private final ConcurrentHashMap<String, ServiceStatus> lastStatusMap = new ConcurrentHashMap<>();
    
    public boolean checkServiceHealth(ServiceConfig config) {
        String serviceKey = config.getHost() + ":" + config.getPort();
        
        try {
            boolean isHealthy = false;
            long responseTime = 0;
            String checkDetails = "";
            long startTime = System.currentTimeMillis();
            switch (config.getProtocol().toLowerCase()) {
                case "tcp":

                    isHealthy = networkUtil.isPortOpen(config.getHost(), config.getPort(), config.getTimeoutMs());
                    responseTime = System.currentTimeMillis() - startTime;
                    checkDetails = String.format("TCP连接检查: %s", isHealthy ? "成功" : "失败");
                    break;
                    
                case "http":
                case "https":
                    if (config.getHealthCheckUrl() != null) {
                        HttpUtil.HttpResponse response = httpUtil.get(config.getHealthCheckUrl(), config.getTimeoutMs());
                        isHealthy = response.isHealthy();
                        responseTime = response.getResponseTimeMs();
                        
                        if (config.getExpectedResponse() != null && isHealthy) {
                            isHealthy = response.getBody().contains(config.getExpectedResponse());
                        }
                        
                        checkDetails = String.format("HTTP检查: 状态码=%d, 响应时间=%dms", 
                            response.getStatusCode(), responseTime);
                    } else {
                        // 如果没有指定健康检查URL，则检查端口
                        isHealthy = networkUtil.isPortOpen(config.getHost(), config.getPort(), config.getTimeoutMs());
                        responseTime = System.currentTimeMillis() - startTime;
                        checkDetails = String.format("%s端口检查: %s", config.getProtocol().toUpperCase(), isHealthy ? "成功" : "失败");
                    }
                    break;
                    
                default:
                    throw new IllegalArgumentException("不支持的协议: " + config.getProtocol());
            }
            
            ServiceStatus currentStatus = new ServiceStatus(config.getName(), serviceKey, isHealthy, 
                responseTime, checkDetails, new Timestamp(System.currentTimeMillis()));
                
            ServiceStatus lastStatus = lastStatusMap.get(serviceKey);
            
            if (lastStatus == null || lastStatus.isHealthy() != isHealthy) {
                logger.info("服务 {} 状态变化: {} -> {}, 响应时间: {}ms", 
                    config.getName(), 
                    lastStatus != null ? (lastStatus.isHealthy() ? "健康" : "异常") : "未知",
                    isHealthy ? "健康" : "异常", 
                    responseTime);
            }
            
            lastStatusMap.put(serviceKey, currentStatus);
            
            return isHealthy;
            
        } catch (Exception e) {
            logger.error("检查服务 {} 健康状态时发生异常", config.getName(), e);
            
            ServiceStatus errorStatus = new ServiceStatus(config.getName(), serviceKey, false, 
                0, "检查异常: " + e.getMessage(), new Timestamp(System.currentTimeMillis()));
            lastStatusMap.put(serviceKey, errorStatus);
            
            return false;
        }
    }
    
    public void recordMonitoringResult(ServiceConfig config, boolean isHealthy) {
        try {
            String serviceKey = config.getHost() + ":" + config.getPort();
            ServiceStatus status = lastStatusMap.get(serviceKey);
            
            if (status != null) {
                logger.debug("记录监控结果: {} - 状态:{}, 响应时间:{}ms, 详情:{}", 
                    config.getName(), isHealthy ? "健康" : "异常", 
                    status.getResponseTimeMs(), status.getCheckDetails());
                
                // 这里可以将监控结果持久化到数据库
                // monitoringResultRepository.save(status);
            }
        } catch (Exception e) {
            logger.error("记录监控结果时发生异常", e);
        }
    }
    
    public void handleServiceAlert(ServiceConfig config, String alertMessage) {
        if (!config.isAlertEnabled()) {
            return;
        }
        
        try {
            String serviceKey = config.getHost() + ":" + config.getPort();
            ServiceStatus currentStatus = lastStatusMap.get(serviceKey);
            ServiceStatus lastStatus = getPreviousStatus(serviceKey);
            
            // 只有在状态从健康变为异常时才发送告警，避免重复告警
            if (lastStatus == null || lastStatus.isHealthy()) {
                String alertTitle = String.format("服务监控告警 - %s", config.getName());
                String alertContent = String.format(
                    "服务: %s\n" +
                    "地址: %s:%d\n" +
                    "协议: %s\n" +
                    "状态: 异常\n" +
                    "时间: %s\n" +
                    "详情: %s",
                    config.getName(),
                    config.getHost(),
                    config.getPort(),
                    config.getProtocol(),
                    currentStatus != null ? currentStatus.getCheckTime() : "未知",
                    alertMessage
                );
                
                alertService.sendAlert(alertTitle, alertContent, config.getAlertEmails());
                
                logger.warn("发送服务告警: {} - {}", config.getName(), alertMessage);
            }
            
        } catch (Exception e) {
            logger.error("处理服务告警时发生异常", e);
        }
    }
    
    private ServiceStatus getPreviousStatus(String serviceKey) {
        // 这里应该从历史记录中获取上一次的状态
        // 简化实现，直接返回null，表示没有历史记录
        return null;
    }
    
    public ServiceStatus getServiceStatus(String host, int port) {
        String serviceKey = host + ":" + port;
        return lastStatusMap.get(serviceKey);
    }
    
    public static class ServiceStatus {
        private String serviceName;
        private String serviceKey;
        private boolean healthy;
        private long responseTimeMs;
        private String checkDetails;
        private Timestamp checkTime;
        
        public ServiceStatus(String serviceName, String serviceKey, boolean healthy, 
                           long responseTimeMs, String checkDetails, Timestamp checkTime) {
            this.serviceName = serviceName;
            this.serviceKey = serviceKey;
            this.healthy = healthy;
            this.responseTimeMs = responseTimeMs;
            this.checkDetails = checkDetails;
            this.checkTime = checkTime;
        }
        
        // Getters
        public String getServiceName() { return serviceName; }
        public String getServiceKey() { return serviceKey; }
        public boolean isHealthy() { return healthy; }
        public long getResponseTimeMs() { return responseTimeMs; }
        public String getCheckDetails() { return checkDetails; }
        public Timestamp getCheckTime() { return checkTime; }
        
        @Override
        public String toString() {
            return String.format("ServiceStatus{name='%s', key='%s', healthy=%s, time=%dms}", 
                serviceName, serviceKey, healthy, responseTimeMs);
        }
    }
}